import {
  Component,
  OnInit,
  ContentChildren,
  QueryList,
  Input,
  EventEmitter,
  Output,
  OnChanges,
  ChangeDetectionStrategy,
  SimpleChanges,
} from '@angular/core';
import { DataTableColumnDirective } from '../../directives/data-table-column.directive';
import { MySelection } from 'app/modules/base/selection';
import { BehaviorSubject } from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router';
import { ListResult } from 'app/modules/base/api-base';

type SortBy = '' | 'desc' | 'asc';
type Sort = { [key: string]: SortBy };

@Component({
  selector: 'm-data-table',
  templateUrl: './data-table.component.html',
  styleUrls: ['./data-table.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DataTableComponent<T extends Object> implements OnInit, OnChanges {
  @ContentChildren(DataTableColumnDirective) columns: QueryList<DataTableColumnDirective>;
  constructor(private route: ActivatedRoute, private router: Router) { }

  // data数据源
  @Input() data: T[] = [];
  // hideColumn 隐藏列表中的行
  @Input() hideColumn: string[] = [];

  @Input() result: ListResult;

  // sortable 标记列表中的行为可排序状态
  @Input() sortable: string[] = [];
  // sortUseRouteQueryParam 排序是否使用查询参数
  @Input() sortUseRouteQueryParam = false;

  // 当前排序状态
  @Input() sort: Sort = { created_at: 'asc' };
  @Output() sortChange = new EventEmitter<Sort>();

  // selection 为空时不显示选择框
  @Input() selection: MySelection<any> = null;
  // 全选状态
  selectedAll$ = new BehaviorSubject(false);

  ngOnInit() {
    // 全选状态
    if (this.selection) {
      this.selection.change.subscribe(() => this.checkIsSelectedAll());
    }
    // 排序状态恢复
    if (this.sortUseRouteQueryParam) {
      this.route.queryParamMap.subscribe(query => {
        const order_by = query.get('order_by');
        const order = query.get('order') as SortBy;
        this.sort = order_by ? { [order_by]: order } : { created_at: 'asc' };
      });
    }
  }

  // data 更改时，判断全选状态
  ngOnChanges(changes: SimpleChanges) {
    if (changes.data && this.selection) {
      this.checkIsSelectedAll();
    }
  }

  // 排序变动
  clickHeader(column: DataTableColumnDirective) {
    if (column.name === 'created_at' || this.sortable.includes(column.name)) {
      const current = this.sort[column.name];
      this.sort = {};
      switch (current) {
        case 'asc':
          if (column.name === 'created_at') {
            this.sort[column.name] = 'desc';
            break;
          }
          this.sort[column.name] = '';
          break;
        case 'desc':
          this.sort[column.name] = 'asc';
          break;
        default:
          this.sort[column.name] = 'desc';
      }
      this.sortChange.emit(this.sort);
      if (this.sortUseRouteQueryParam) {
        let queryParams = { ...this.route.snapshot.queryParams, page: 1 };
        if (this.sort[column.name]) {
          const order_by = { order_by: column.name, order: this.sort[column.name] };
          queryParams = { ...queryParams, ...order_by };
        } else {
          delete queryParams['order_by'];
          delete queryParams['order'];
        }
        this.router.navigate([], { queryParams });
      }
    }
  }

  // 触发选择
  toggle(value: boolean, data: T[]) {
    if (value) {
      this.selection.select(...data);
    } else {
      this.selection.unselect(...data);
    }
  }

  // 检查当前是否已全选
  checkIsSelectedAll() {
    if (!this.data || !this.data.length) {
      return false;
    }
    this.selectedAll$.next(this.selection.isSelected(...this.data));
  }
}
